Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Commit 3b5630474d9d6650f45c96079953a876590daa4b


Parents : 2b930f7
Author : Ivan <ivan@quad4.io>
Signature : Signature validation error
Date : 2026-05-03T14:03:18-05:00

feat(codec2): implement locateFile function for WASM asset resolution and update integrity checks

Changes
Diff

diff --git a/meshchatx/src/frontend/public/assets/js/codec2-emscripten/codec2-lib.js b/meshchatx/src/frontend/public/assets/js/codec2-emscripten/codec2-lib.js
index 3b1f5176..1bde440e 100644
--- a/meshchatx/src/frontend/public/assets/js/codec2-emscripten/codec2-lib.js
+++ b/meshchatx/src/frontend/public/assets/js/codec2-emscripten/codec2-lib.js
@@ -1,3 +1,17 @@
+/**
+ * Emscripten resolves .wasm next to the script URL. Codec2Loader injects these
+ * scripts from blob: URLs (SRI), so scriptDirectory is opaque and WASM fetch
+ * fails unless we pin assets to same-origin paths (notably Android WebView).
+ */
+function codec2EmscriptenLocateFile(path) {
+ const base = "/assets/js/codec2-emscripten";
+ const p = String(path || "").replace(/^\.\//, "");
+ if (p.startsWith("/")) {
+ return base + p;
+ }
+ return `${base}/${p}`;
+}
+
class Codec2Lib {
static arrayBufferToBase64(buffer) {
let binary = "";
@@ -30,6 +44,7 @@ class Codec2Lib {
static runDecode(mode, data) {
return new Promise((resolve, reject) => {
const module = {
+ locateFile: codec2EmscriptenLocateFile,
arguments: [mode, "input.bit", "output.raw"],
preRun: () => {
module.FS.writeFile("input.bit", new Uint8Array(data));
@@ -48,6 +63,7 @@ class Codec2Lib {
static runEncode(mode, data) {
return new Promise((resolve, reject) => {
const module = {
+ locateFile: codec2EmscriptenLocateFile,
arguments: [mode, "input.raw", "output.bit"],
preRun: () => {
module.FS.writeFile("input.raw", new Uint8Array(data));
@@ -66,6 +82,7 @@ class Codec2Lib {
static rawToWav(buffer) {
return new Promise((resolve, reject) => {
const module = {
+ locateFile: codec2EmscriptenLocateFile,
arguments: [
"-r",
"8000",
@@ -96,6 +113,7 @@ class Codec2Lib {
static audioFileToRaw(buffer, filename) {
return new Promise((resolve, reject) => {
const module = {
+ locateFile: codec2EmscriptenLocateFile,
arguments: [filename, "-r", "8000", "-L", "-e", "signed-integer", "-b", "16", "-c", "1", "output.raw"],
preRun: () => {
module.FS.writeFile(filename, new Uint8Array(buffer));

diff --git a/meshchatx/src/frontend/public/assets/js/codec2-emscripten/codec2-microphone-recorder.js b/meshchatx/src/frontend/public/assets/js/codec2-emscripten/codec2-microphone-recorder.js
index d7ac2af8..ecfc9ce0 100644
--- a/meshchatx/src/frontend/public/assets/js/codec2-emscripten/codec2-microphone-recorder.js
+++ b/meshchatx/src/frontend/public/assets/js/codec2-emscripten/codec2-microphone-recorder.js
@@ -51,7 +51,9 @@ class Codec2MicrophoneRecorder {
typeof globalThis.AudioWorkletNode === "function"
) {
try {
- await this.audioContext.audioWorklet.addModule("assets/js/codec2-emscripten/processor.js");
+ await this.audioContext.audioWorklet.addModule(
+ "/assets/js/codec2-emscripten/processor.js"
+ );
const wn = new AudioWorkletNode(this.audioContext, "audio-processor");
wn.port.onmessage = async (event) => {
this.audioChunks.push(event.data);

diff --git a/meshchatx/src/frontend/public/assets/js/codec2-emscripten/integrity.json b/meshchatx/src/frontend/public/assets/js/codec2-emscripten/integrity.json
index 0b17bb09..84e18a98 100644
--- a/meshchatx/src/frontend/public/assets/js/codec2-emscripten/integrity.json
+++ b/meshchatx/src/frontend/public/assets/js/codec2-emscripten/integrity.json
@@ -7,8 +7,8 @@
"c2enc.js": "sha384-Rrnbr/tbCaDiL1n14+MccgIw0Cef+yrpbdYythu5/PkpzZhsVc+9Fle0WyT+7AWc",
"sox.wasm": "sha384-NMa5LHokdsVBdaUPlK1jnsSQ1nmgAnf8POPAwFpRkfjckdBCUSs1RhRd03CHwDAN",
"sox.js": "sha384-iSAIvLWRyVYwMrKhVzrmvcCzS5noiipjTxOowhXWkmDW0xFGjLV8YGpppX1qRdum",
- "codec2-lib.js": "sha384-ts/lRDKjHaqD4pUZeyXI+nMIe75khxJEcORRLiqaJo496FFa1FSkfKzW2lm9RAus",
- "codec2-microphone-recorder.js": "sha384-dGQR+cfKn/lejCt32+N8EJw94+VwFvTeFILKDo1BOm0R+1qElYCR+jrPHezOEzb9",
+ "codec2-lib.js": "sha384-zsX9uAMRA7ZBjLcgR/uc2ZKNnyd41x3/KyKl7NMxTBQ8fXVH+RzNfOmBpVyQmvet",
+ "codec2-microphone-recorder.js": "sha384-Akn96VRTRXneZSwV4ocrapOCdrKAR0oilBW2KuEamp2cvPMayG+vhS0e2tTjXr/m",
"processor.js": "sha384-m1JmxQg3+KdNiu25A6ArCGFaaKmN6MzONe+LaphWLPfwXqs8bxD6dWNbehUUG54Y",
"wav-encoder.js": "sha384-QToS0oLeqMQo+9wYKkx+pTNlBRZsRKsKplmJB/Plf3LwngxNi+0YFJBkb17aCNIM"
}


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────